#pragma once

using namespace System;
using namespace System::Collections::Generic;
using namespace System::IO;
using namespace NUnit::Framework;
using namespace LatoolNet;

namespace LatoolNetTest {

	[TestFixture]
	public ref class PolynomialFittingTest {
	public:

		[Test]
		void TestApprox() {

			Random^ randgen = gcnew Random();
			double a = randgen->NextDouble() * 10 - 5;
			double b = randgen->NextDouble() * 10 - 5;
			double c = randgen->NextDouble() * 10 - 5;

			array<double>^ x = gcnew array<double>(10);
			array<double>^ y = gcnew array<double>(10);

			for (int i = 0; i < 10; i++) {
				x[i] = i;
				y[i] = a * x[i] * x[i] + b * x[i] + c;
			}

			Polynomial^ poly = PolynomialFitting::Fit(x, y, 2);

			array<double>^ coef = poly->Coefs;
			double average = poly->Offset;
			
			for (int i = 0; i < 20; i++) {
				double rand = randgen->NextDouble() * 10 - 5;
				double expected = a * rand * rand + b * rand + c;
				double actual = poly->Value(rand);
				double actualByManual = coef[2] * (rand - average) * (rand - average) + coef[1] * (rand - average) + coef[0];
				Assert::AreEqual(expected, actual, 1e-10, "Test: PolynomialFitting");
				Assert::AreEqual(expected, actualByManual, 1e-10, "Test: PolynomialFitting");
			}
		};

	};
}
